﻿using Core.Dtos;
using Core.Entities;
using Core.IRepository;
using Core.Messages;
using Core.Queries;
using Library.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;

namespace Front.Controllers.Api
{
    public class CrudBaseController<TId, TEntity, TDto, TQuery> : ReadBaseController<TId, TEntity, TDto, TQuery>
        where TDto : BaseDto<TId>
        where TEntity : BaseEntity<TId>
        where TQuery : BaseQuery<TEntity>
    {
        public CrudBaseController(IUnitOfWork unitOfWork, IBaseRepository<TId, TEntity> Repository):
            base(unitOfWork, Repository)
        {
            this.UnitOfWork = unitOfWork;
            this.Repository = Repository;
        }

        protected virtual void DefaultAddEdit_SetForeignRelationsOnEntity(TEntity entity, TDto requestDto)
        {
        }

        // POST api/<controller>
        protected BaseResponse<TId> DefaultAdd(TDto dto)
        {           
            BaseResponse<TId> response = new BaseResponse<TId>();
            try
            {
                TEntity entity = AutoMapper.Mapper.Map<TDto, TEntity>(dto);
                DefaultAddEdit_SetForeignRelationsOnEntity(entity, dto);

                if (entity.Validate())
                {
                    Repository.Add(entity);
                    UnitOfWork.Commit();
                    response.Value = entity.IdValue;
                    response.Success = true;
                }
                else
                {
                    response.Success = false;
                    response.BrokenRules = entity.BrokenRules;
                }
            }
            catch (Exception ex)
            {
                response.Success = false;
                response.ErrorMessage = ex.ToString();
            }

            return response;
        }

        protected BaseResponse DefaultEdit(TId id, TDto dto)
        {
            BaseResponse response = new BaseResponse();
            try
            {                
                TEntity entity = Repository.FindBy(id);
                AutoMapper.Mapper.Map<TDto, TEntity>(dto, entity);
                DefaultAddEdit_SetForeignRelationsOnEntity(entity, dto);

                if (entity.Validate())
                {
                    Repository.Edit(entity);
                    UnitOfWork.Commit();
                    response.Success = true;
                }
                else
                {
                    response.Success = false;
                    response.BrokenRules = entity.BrokenRules;
                }
            }
            catch (Exception ex)
            {
                response.Success = false;
                response.ErrorMessage = ex.ToString();               
            }

            return response;
        }


        // DELETE api/<controller>/5
        public virtual BaseResponse Delete(TId id)
        {
            BaseResponse response = new BaseResponse();
            try
            {
                TEntity entity = Repository.FindBy(id);
                Repository.Delete(entity);
                UnitOfWork.Commit();
                response.Success = true;
            }
            catch (Exception ex)
            {
                response.Success = false;
                response.ErrorMessage = ex.ToString();
            }

            return response;
        }
    }
}
